#include "options.h"

#include "zrpc/base/timer.h"

namespace libraft {
static void Split(const std::string& str, char delim,
                  std::vector<std::string>* tokens) {
  tokens->clear();
  size_t prev_pos = str.find_first_not_of(delim, 0);
  size_t pos = str.find(delim, prev_pos);

  while (prev_pos != std::string::npos || pos != std::string::npos) {
    std::string token(str.substr(prev_pos, pos - prev_pos));
    tokens->push_back(token);

    prev_pos = str.find_first_not_of(delim, pos);
    pos = str.find_first_of(delim, prev_pos);
  }
}

Options::Options()
    : local_ip("127.0.0.1"),
      local_port(10086),
      db_path("./raft_db"),
      log_path("./raft_log_db"),
      check_leader_us(6000000),
      heart_beat_us(3000000),
      append_entries_size_once(10240000),
      append_entries_count_once(102400),
      single_mode(false),
      add_current_term(0),
      destory(true) {}

Options::Options(const std::string& cluster_string, const std::string& local_ip,
                 int local_port, const std::string& db_path,
                 const std::string& meta_path, const std::string& log_path,
                 bool destory)
    : local_ip(local_ip),
      local_port(local_port),
      db_path(db_path),
      log_path(log_path),
      meta_path(meta_path),
      check_leader_us(6000000),
      heart_beat_us(3000000),
      append_entries_size_once(10240000),
      append_entries_count_once(102400),
      single_mode(false),
      add_current_term(0),
      destory(destory) {
  std::srand(zrpc::TimeStamp::NowMicros());
  Split(cluster_string, ',', &members);
  if (members.size() == 1) {
    single_mode = true;
  }
}

void Options::SetAddCurrentTerm(uint32_t add) { add_current_term = add; }

void Options::SetMembers(const std::string& cluster_string) {
  Split(cluster_string, ',', &members);
  if (members.size() == 1) {
    single_mode = true;
  }
}

std::string Options::ToString() {
  char str[1024];
  int len = 0;
  for (size_t i = 0; i < members.size(); i++) {
    len +=
        snprintf(str + len, sizeof(str), "                 member %lu : %s\n",
                 i, members[i].c_str());
  }
  snprintf(str + len, sizeof(str),
           "                 local_ip : %s\n"
           "               local_port : %d\n"
           "                     path : %s\n"
           "          check_leader_us : %ld\n"
           "             heartbeat_us : %ld\n"
           " append_entries_size_once : %ld\n"
           "append_entries_count_once : %lu\n"
           "              single_mode : %s\n",
           local_ip.c_str(), local_port, db_path.c_str(), check_leader_us,
           heart_beat_us, append_entries_size_once, append_entries_count_once,
           single_mode ? "true" : "false");
  return str;
}

void Options::Dump() {
  for (size_t i = 0; i < members.size(); i++) {
    printf("               member %lu : %s\n", i, members[i].c_str());
  }

  printf(
      "                 local_ip : %s\n"
      "               local_port : %d\n"
      "                     path : %s\n"
      "          check_leader_us : %ld\n"
      "             heartbeat_us : %ld\n"
      " append_entries_size_once : %ld\n"
      "append_entries_count_once : %lu\n"
      "              single_mode : %s\n\n",
      local_ip.c_str(), local_port, db_path.c_str(), check_leader_us,
      heart_beat_us, append_entries_size_once, append_entries_count_once,
      single_mode ? "true" : "false");
}

}  // namespace libraft